<!DOCTYPE html>
<html lang="en">
  <head>
    <title>
        Java-framework-SpringBoot-2 - rulerLwx Blog
      </title>
        <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="format-detection" content="telephone=no,email=no,adress=no">
    
    <meta name="theme-color" content="#000000" />
    
    <meta http-equiv="window-target" content="_top" />
    
    
    <meta name="description" content="本笔记学习资料：https://ke.qq.com/course/403245?taid=3394046366459693 如果失效了，到尚硅" />
    <meta name="generator" content="Hugo 0.73.0 with theme pure" />
    <title>Java-framework-SpringBoot-2 - rulerLwx Blog</title>
    
    
    <link rel="stylesheet" href="https://rulerLwx.gitee.io/css/style.min.c4bc7071f132c964c2116bca53b392933f377e5ca7b7051ed245187c621a2d3e.css">
    
    <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/9.15.10/styles/github.min.css" async>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.css" async>
    <meta property="og:title" content="Java-framework-SpringBoot-2" />
<meta property="og:description" content="本笔记学习资料：https://ke.qq.com/course/403245?taid=3394046366459693 如果失效了，到尚硅" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://rulerLwx.gitee.io/2020/07/java-framework-springboot-2/" />
<meta property="article:published_time" content="2020-07-01T18:58:47+08:00" />
<meta property="article:modified_time" content="2020-07-01T18:58:47+08:00" />
<meta itemprop="name" content="Java-framework-SpringBoot-2">
<meta itemprop="description" content="本笔记学习资料：https://ke.qq.com/course/403245?taid=3394046366459693 如果失效了，到尚硅">
<meta itemprop="datePublished" content="2020-07-01T18:58:47&#43;08:00" />
<meta itemprop="dateModified" content="2020-07-01T18:58:47&#43;08:00" />
<meta itemprop="wordCount" content="4518">



<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Java-framework-SpringBoot-2"/>
<meta name="twitter:description" content="本笔记学习资料：https://ke.qq.com/course/403245?taid=3394046366459693 如果失效了，到尚硅"/>

    <!--[if lte IE 9]>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20170427/classList.min.js"></script>
      <![endif]-->

    <!--[if lt IE 9]>
        <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
      <![endif]-->
  </head>

  
  

  <body class="main-center theme-black" itemscope itemtype="http://schema.org/WebPage"><header class="header" itemscope itemtype="http://schema.org/WPHeader">
    <div class="slimContent">
      <div class="navbar-header">
        <div class="profile-block text-center">
          <a id="avatar" href="https://gitee.com/rulerLwx" target="_blank">
            <img class="img-circle img-rotate" src="https://rulerLwx.gitee.io/avatar.png" width="200" height="200">
          </a>
          <h2 id="name" class="hidden-xs hidden-sm">rulerLwx</h2>
          <h3 id="title" class="hidden-xs hidden-sm hidden-md">thinking...</h3>
          <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i>Guangzhou, China</small>
        </div><div class="search" id="search-form-wrap">
    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="Search" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i
                        class="icon icon-search"></i></button>
            </span>
        </div>
        <div class="ins-search">
            <div class="ins-search-mask"></div>
            <div class="ins-search-container">
                <div class="ins-input-wrapper">
                    <input type="text" class="ins-search-input" placeholder="Type something..."
                        x-webkit-speech />
                    <button type="button" class="close ins-close ins-selectable" data-dismiss="modal"
                        aria-label="Close"><span aria-hidden="true">×</span></button>
                </div>
                <div class="ins-section-wrapper">
                    <div class="ins-section-container"></div>
                </div>
            </div>
        </div>
    </form>
</div>
        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
      </div>
      <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
        <ul class="nav navbar-nav main-nav">
            <li class="menu-item menu-item-home">
                <a href="/">
                    <i class="icon icon-home-fill"></i>
                  <span class="menu-title">Home</span>
                </a>
            </li>
            <li class="menu-item menu-item-archives">
                <a href="/posts/">
                    <i class="icon icon-archives-fill"></i>
                  <span class="menu-title">Archives</span>
                </a>
            </li>
            <li class="menu-item menu-item-categories">
                <a href="/categories/">
                    <i class="icon icon-folder"></i>
                  <span class="menu-title">Categories</span>
                </a>
            </li>
            <li class="menu-item menu-item-tags">
                <a href="/tags/">
                    <i class="icon icon-tags"></i>
                  <span class="menu-title">Tags</span>
                </a>
            </li>
            <li class="menu-item menu-item-about">
                <a href="/about/">
                    <i class="icon icon-cup-fill"></i>
                  <span class="menu-title">About</span>
                </a>
            </li>
        </ul>
      </nav>
    </div>
  </header>

<aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">Board</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">enjoy~
            </div>
        </div>
    </div>
</div>

      <div class="widget">
    <h3 class="widget-title"> Categories</h3>
    <div class="widget-body">
        <ul class="category-list">
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-framework/" class="category-list-link">java-framework</a><span class="category-list-count">38</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-front-end/" class="category-list-link">java-front-end</a><span class="category-list-count">11</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-se/" class="category-list-link">java-se</a><span class="category-list-count">21</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-senior/" class="category-list-link">java-senior</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/linux/" class="category-list-link">linux</a><span class="category-list-count">13</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/tools/" class="category-list-link">tools</a><span class="category-list-count">1</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%8A%80%E6%9C%AF%E6%9D%82%E7%83%A9/" class="category-list-link">技术杂烩</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/" class="category-list-link">数据库</a><span class="category-list-count">15</span></li>
        </ul>
    </div>
</div>
      <div class="widget">
    <h3 class="widget-title"> Tags</h3>
    <div class="widget-body">
        <ul class="tag-list">
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/jvm/" class="tag-list-link">jvm</a><span
                    class="tag-list-count">1</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" class="tag-list-link">多线程</a><span
                    class="tag-list-count">2</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/" class="tag-list-link">网络编程</a><span
                    class="tag-list-count">3</span></li>
            
        </ul>

    </div>
</div>
      
<div class="widget">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget-body">
        <ul class="recent-post-list list-unstyled no-thumbnail">
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E4%B8%80%E6%89%B9%E9%87%8F%E7%A7%BB%E5%8A%A8%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6/" class="title">自己动手（一）——批量移动、重命名文件</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-27 17:50:02 &#43;0800 CST" itemprop="datePublished">2020-07-27</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E5%85%B3%E4%BA%8Einteger%E7%9A%84-128~127%E7%BC%93%E5%AD%98/" class="title">关于Integer的 -128~127缓存</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-11 16:56:21 &#43;0800 CST" itemprop="datePublished">2020-07-11</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/" class="title">跨域问题</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-08 22:41:12 &#43;0800 CST" itemprop="datePublished">2020-07-08</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/" class="title">个人博客搭建</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-05 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-05</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/centos/" class="title">CentOS-</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-01 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-01</time>
                    </p>
                </div>
            </li>
        </ul>
    </div>
</div>
  </div>
</aside>

    
    
<aside class="sidebar sidebar-toc collapse" id="collapseToc" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    <h4 class="toc-title">Catalogue</h4>
    <nav id="toc" class="js-toc toc">

    </nav>
  </div>
</aside>
<main class="main" role="main"><div class="content">
  <article id="-" class="article article-type-" itemscope
    itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      <h1 itemprop="name">
  <a
    class="article-title"
    href="/2020/07/java-framework-springboot-2/"
    >Java-framework-SpringBoot-2</a
  >
</h1>

      <div class="article-meta">
        
<span class="article-date">
  <i class="icon icon-calendar-check"></i>&nbsp;
<a href="https://rulerLwx.gitee.io/2020/07/java-framework-springboot-2/" class="article-date">
  <time datetime="2020-07-01 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-01</time>
</a>
</span>
<span class="article-category">
  <i class="icon icon-folder"></i>&nbsp;
  <a class="article-category-link" href="/categories/java-framework/"> Java-framework </a>
</span>

        <span class="post-comment"><i class="icon icon-comment"></i>&nbsp;<a href="/2020/07/java-framework-springboot-2/#comments"
            class="article-comment-link">Comments</a></span>
		<span class="post-wordcount hidden-xs" itemprop="wordCount">Word Count: 4518words</span>
		<span class="post-readcount hidden-xs" itemprop="timeRequired">Read Count: 10minutes </span>
      </div>
    </div>
    <div class="article-entry marked-body js-toc-content" itemprop="articleBody">
      <hr>
<p>本笔记学习资料：https://ke.qq.com/course/403245?taid=3394046366459693</p>
<p>如果失效了，到尚硅谷官网找：http://www.atguigu.com/download.shtml</p>
<hr>
<h1 id="文件上传">文件上传</h1>
<p>不需要导入额外的包，只需要有 spring-boot-starter-web 依赖即可。</p>
<p>页面、控制类写法同SpriingMVC，参考《Java-framework-SpringMVC-2》。</p>
<p>Spring Boot需要在application.properties文件配置上传文件大小：</p>
<pre><code>spring.servlet.multipart.max-file-size=300MB
spring.servlet.multipart.max-request-size=300MB
</code></pre>
<h1 id="数据检验hibernate-validate">数据检验：hibernate-validate</h1>
<blockquote>
<p>跟 Spring MVC 数据校验一致，参考《Java-framework-SpringMVC-2》之表单校验。</p>
<p>也可以使用全局异常类来处理校验返回的结果 ——20190820</p>
<p>参考：https://github.com/keeperLee/miaosha_1/tree/master/src/main/java/com/imooc/miaosha/exception</p>
</blockquote>
<p>1）在实体类字段上添加注解校验规则</p>
<pre><code class="language-java">public class Users {
	@NotBlank(message=&quot;用户名不能为空&quot;) //非空校验
	@Length(min=2,max=6,message=&quot;最小长度为2位，最大长度为6位&quot;)
	private String name;
	@NotEmpty
	private String password;
	@Min(value=15)
	private Integer age;
	@Email
	private String email;
	
	//set/get...
}
</code></pre>
<p>2）在controller方法中使用@Valid和BindingResult</p>
<pre><code>@Controller
public class UsersController {

	@RequestMapping(&quot;/addUser&quot;)
	public String showPage(@ModelAttribute(&quot;aa&quot;) Users users){
		return &quot;add&quot;;
	}

	@RequestMapping(&quot;/save&quot;)
	public String saveUser(@ModelAttribute(&quot;aa&quot;) @Valid Users users,BindingResult result){
		if(result.hasErrors()){
			return &quot;add&quot;;
		}
		System.out.println(users);
		return &quot;ok&quot;;
	}
}
</code></pre>
<p>BindingResult会将校验结果以<code>users</code>作为key，对应的校验结果文本（message）作为value进行返回。</p>
<p>key遵循驼峰命名规则，即 Users 类对应 users。</p>
<p>如果想为传递的对象更改名称，可以使用@ModelAttribute(&ldquo;aa&rdquo;)这表示当前传递的对象的key为aa。</p>
<p>那么我们在页面中获取该对象的key也需要修改为aa</p>
<p>3） 页面</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;title&gt;添加用户&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;form th:action=&quot;@{/save}&quot; method=&quot;post&quot;&gt;
		用户姓名：&lt;input type=&quot;text&quot; name=&quot;name&quot;/&gt;&lt;font color=&quot;red&quot; th:errors=&quot;${aa.name}&quot;&gt;&lt;/font&gt;&lt;br/&gt;
		用户密码：&lt;input type=&quot;password&quot; name=&quot;password&quot; /&gt;&lt;font color=&quot;red&quot; th:errors=&quot;${aa.password}&quot;&gt;&lt;/font&gt;&lt;br/&gt;
		用户年龄：&lt;input type=&quot;text&quot; name=&quot;age&quot; /&gt;&lt;font color=&quot;red&quot; th:errors=&quot;${aa.age}&quot;&gt;&lt;/font&gt;&lt;br/&gt;
		用户邮箱：&lt;input type=&quot;text&quot; name=&quot;email&quot; /&gt;&lt;font color=&quot;red&quot; th:errors=&quot;${aa.email}&quot;&gt;&lt;/font&gt;&lt;br/&gt;
		&lt;input type=&quot;submit&quot; value=&quot;OK&quot;/&gt;
	&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>几个注解规则解释：</p>
<ul>
<li>@NotBlank: 判断字符串是否为null 或者是空串(<strong>去掉首尾空格</strong>)。</li>
<li>@NotEmpty: 判断字符串是否null 或者是空串。</li>
<li>@Length: 判断字符的长度(最大或者最小)</li>
<li>@Min: 判断数值最小值</li>
<li>@Max: 判断数值最大值</li>
<li>@Email: 判断邮箱是否合法</li>
</ul>
<h1 id="异常处理">异常处理</h1>
<p>SpringBoot 提供了五种异常处理方式</p>
<ul>
<li>自定义错误页面</li>
<li>@ExceptionHandle 注解处理异常</li>
<li>@ControllerAdvice + @ExceptionHandler 注解处理异常</li>
<li>配置 SimpleMappingExceptionResolver 处理异常</li>
<li>自定义 HandlerExceptionResolver 类处理异常</li>
</ul>
<p>跟 Spring MVC 结合起来一直学习。</p>
<h2 id="自定义错误页面">自定义错误页面</h2>
<p>SpringBoot 默认的已经提供了一套处理异常的机制。</p>
<p>一旦程序中出现了异常SpringBoot 会像/error 的 url 发送请求。在springBoot 中提供了一个叫 BasicExceptionController 来处理/error 请求，然后跳转到 src/main/resources/templates 目录下的 error.html。</p>
<p>error.html 就是我们自定义的错误页面。</p>
<h2 id="exceptionhandle-注解处理异常">@ExceptionHandle 注解处理异常</h2>
<p>同 Spring MVC，参考《Java-framework-SpringMVC-2》之异常处理。</p>
<h2 id="controlleradvice--exceptionhandler-注解处理异常">@ControllerAdvice + @ExceptionHandler 注解处理异常</h2>
<p>同 Spring MVC，参考《Java-framework-SpringMVC-2》之异常处理。</p>
<h2 id="simplemappingexceptionresolver-处理异">SimpleMappingExceptionResolver 处理异</h2>
<p>同 Spring MVC，参考《Java-framework-SpringMVC-2》之异常处理。</p>
<p>其实就是将 xml 配置转为“零配置”方式。</p>
<pre><code class="language-java">/**
 * 通过SimpleMappingExceptionResolver做全局异常处理
 */
@Configuration
public class GlobalException {
	
	/**
	 * 该方法必须要有返回值。返回值类型必须是：SimpleMappingExceptionResolver
	 */
	@Bean
	public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
		SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
		
		Properties mappings = new Properties();
		
		/**
		 * 参数一：异常的类型，注意必须是异常类型的全名
		 * 参数二：视图名称
		 */
		mappings.put(&quot;java.lang.ArithmeticException&quot;, &quot;error1&quot;);
		mappings.put(&quot;java.lang.NullPointerException&quot;,&quot;error2&quot;);
		
		//设置异常与视图映射信息的
		resolver.setExceptionMappings(mappings);
		
		return resolver;
	}
}
</code></pre>
<p>这种方式的缺点：无法传递异常信息到页面。</p>
<h2 id="自定义-handlerexceptionresolver-类处理异常">自定义 HandlerExceptionResolver 类处理异常</h2>
<p>实现 HandlerExceptionResolver 接口</p>
<pre><code class="language-java">/**
 * 通过实现HandlerExceptionResolver接口做全局异常处理
 */
@Configuration
public class GlobalException implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		ModelAndView mv = new ModelAndView();
		//判断不同异常类型，做不同视图跳转
		if(ex instanceof ArithmeticException){
			mv.setViewName(&quot;error1&quot;);
		}
		
		if(ex instanceof NullPointerException){
			mv.setViewName(&quot;error2&quot;);
		}
		mv.addObject(&quot;error&quot;, ex.toString());
		
		return mv;
	}
}
</code></pre>
<h2 id="示例博客demo">示例、博客、demo</h2>
<p><a href="https://www.cnblogs.com/hongdada/p/9179053.html">https://www.cnblogs.com/hongdada/p/9179053.html</a></p>
<h1 id="spring-boot-test">Spring Boot Test</h1>
<p>依赖</p>
<pre><code class="language-xml">    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
    &lt;/dependency&gt;
</code></pre>
<p>测试类</p>
<pre><code class="language-java">/**
 * SpringBoot测试类
 *@RunWith:启动器 
 *SpringJUnit4ClassRunner.class：让junit与spring环境进行整合
 *
 *@SpringBootTest(classes={App.class})有两层含义：
 * 1,当前类为springBoot的测试类
 * 2,加载SpringBoot启动类。启动springBoot
 *
 *junit与spring整合 @Contextconfiguartion(&quot;classpath:applicationContext.xml&quot;)
 */
@RunWith(SpringJUnit4ClassRunner.class) 
@SpringBootTest(classes={App.class})
public class UserServiceTest {

	@Autowired
	private UserServiceImpl userServiceImpl;
	
	@Test
	public void testAddUser(){
		this.userServiceImpl.addUser();
	}
}
</code></pre>
<h1 id="热部署">热部署</h1>
<p>SprigBoot 的热部署方式分为两种</p>
<ul>
<li>SpringLoader 插件</li>
<li>DevTools 工具</li>
</ul>
<h2 id="springloader-方式">SpringLoader 方式</h2>
<p>方式一：以maven 插件方式</p>
<pre><code class="language-xml">    &lt;!-- springloader插件 --&gt;
    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
                &lt;dependencies&gt;
                    &lt;dependency&gt;
                        &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                        &lt;artifactId&gt;springloaded&lt;/artifactId&gt;
                        &lt;version&gt;1.2.5.RELEASE&lt;/version&gt;
                    &lt;/dependency&gt;
                &lt;/dependencies&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;
</code></pre>
<p>热部署操作：</p>
<ol>
<li>正常启动 Spring Boot 项目</li>
<li>修改后台代码后，通过执行 maven 命令 spring-boot:run 进行热部署</li>
</ol>
<p>缺点：1）只对后台代码做部署处理，对页面无能为力；2）以后台进程方式运行，占用端口，需手动关闭进程</p>
<p>结论：不用这种方式。</p>
<p>方式二：将 springloaded 的jar包放到lib目录</p>
<p>结论：不好用。</p>
<h2 id="devtools-方式">DevTools 方式</h2>
<p>1）SpringLoader 与 DevTools 的区别：</p>
<ul>
<li>SpringLoader：SpringLoader 在部署项目时使用的是热部署的方式。</li>
<li>DevTools：DevTools 在部署项目时使用的是重新部署的方式</li>
</ul>
<p>2）使用 DevTools</p>
<pre><code class="language-xml">    &lt;dependencies&gt;
        &lt;!-- DevTools的坐标 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
            &lt;optional&gt;true&lt;/optional&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
</code></pre>
<p>后台、页面修改后，项目会自动重新部署，不需要手动执行任务命令。（eclipse）</p>
<p>但在 IntelliJ 中要做一些配置才行</p>
<p>参考：https://www.cnblogs.com/MrSi/p/9540730.html，https://blog.csdn.net/qq_31293575/article/details/80654132</p>
<h1 id="thymeleaf">thymeleaf</h1>
<h2 id="引擎原理">引擎原理</h2>
<p>所有的模板引擎都是这个原理，只是模板的语法不同</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708100715.png" alt=""></p>
<h2 id="导入依赖">导入依赖</h2>
<p>修改版本，thymeleaf3跟thymeleaf-layout-dialect2以上搭配使用</p>
<p>参考：https://docs.spring.io/spring-boot/docs/1.5.21.RELEASE/reference/htmlsingle/#howto-use-thymeleaf-3</p>
<pre><code>&lt;properties&gt;
    &lt;thymeleaf.version&gt;3.0.2.RELEASE&lt;/thymeleaf.version&gt;
    &lt;thymeleaf-layout-dialect.version&gt;2.1.1&lt;/thymeleaf-layout-dialect.version&gt;
&lt;/properties&gt;
</code></pre>
<p>引入依赖</p>
<pre><code class="language-xml">    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
</code></pre>
<h2 id="thymeleaf默认配置">thymeleaf默认配置</h2>
<p>SpringBoot在自动配置时已经对thymeleaf做了默认的配置，</p>
<p>参考：org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties</p>
<pre><code class="language-java">@ConfigurationProperties(prefix = &quot;spring.thymeleaf&quot;)
public class ThymeleafProperties {

	private static final Charset DEFAULT_ENCODING = Charset.forName(&quot;UTF-8&quot;);

	private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf(&quot;text/html&quot;);

	public static final String DEFAULT_PREFIX = &quot;classpath:/templates/&quot;;

	public static final String DEFAULT_SUFFIX = &quot;.html&quot;;

</code></pre>
<h2 id="thymeleaf语法">thymeleaf语法</h2>
<p>官网：https://www.thymeleaf.org/</p>
<p>使用thymeleaf第一步：导入命名空间<code>xmlns:th=&quot;http://www.thymeleaf.org</code>，如下：</p>
<pre><code class="language-xml">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot; xmlns:th=&quot;http://www.thymeleaf.org&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;thymeleaf测试&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>th:text;改变当前元素里面的文本内容；</p>
<p>th:任意html属性；可替换原生属性的值。</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708100747.png" alt=""></p>
<p>图片内容来自：https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#attribute-precedence</p>
<p>可以用哪些表达式？</p>
<pre><code>Simple expressions:
    Variable Expressions: ${...}
    Selection Variable Expressions: *{...}：配合 th:object 使用
    Message Expressions: #{...}：国际化
    Link URL Expressions: @{...}：定义URL
    Fragment Expressions: ~{...}：
Literals
    Text literals: 'one text', 'Another one!',…
    Number literals: 0, 34, 3.0, 12.3,…
    Boolean literals: true, false
    Null literal: null
    Literal tokens: one, sometext, main,…
Text operations:
    String concatenation: +
    Literal substitutions: |The name is ${name}|
Arithmetic operations:
    Binary operators: +, -, *, /, %
    Minus sign (unary operator): -
Boolean operations:
    Binary operators: and, or
    Boolean negation (unary operator): !, not
Comparisons and equality:
    Comparators: &gt;, &lt;, &gt;=, &lt;= (gt, lt, ge, le)
    Equality operators: ==, != (eq, ne)
Conditional operators:
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
Special tokens:
    No-Operation: _
</code></pre>
<p>参考：https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#standard-expression-syntax</p>
<h2 id="如何使用webjar">如何使用webjar</h2>
<p>官网：https://www.webjars.org/</p>
<pre><code class="language-html">	&lt;!-- Bootstrap core CSS --&gt;
	&lt;link href=&quot;asserts/css/bootstrap.min.css&quot; th:href=&quot;@{/webjars/bootstrap/4.0.0/css/bootstrap.css}&quot; rel=&quot;stylesheet&quot;&gt;
	&lt;!-- Custom styles for this template --&gt;
	&lt;link href=&quot;asserts/css/signin.css&quot; th:href=&quot;@{/asserts/css/signin.css}&quot; rel=&quot;stylesheet&quot;&gt;
</code></pre>
<p><code>@{/asserts/css/signin.css}</code>表示 resources/static目录下的 asserts目录 ——20190818</p>
<h1 id="国际化">国际化</h1>
<p>1）编写国际化文件</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708100812.png" alt=""></p>
<p>2）配置ResourceBundleMessageSource</p>
<p>SpringBoot自动配置好了ResourceBundleMessageSource</p>
<p>查看<code>org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration</code>源码，</p>
<p>可以看到<code>@ConfigurationProperties(prefix = &quot;spring.messages&quot;)</code></p>
<pre><code class="language-java">@ConfigurationProperties(prefix = &quot;spring.messages&quot;)
public class MessageSourceAutoConfiguration {

	private static final Resource[] NO_RESOURCES = {};

	/**
	 * Comma-separated list of basenames (essentially a fully-qualified classpath
	 * location), each following the ResourceBundle convention with relaxed support for
	 * slash based locations. If it doesn't contain a package qualifier (such as
	 * &quot;org.mypackage&quot;), it will be resolved from the classpath root.
	 */
	private String basename = &quot;messages&quot;;
</code></pre>
<p>因此，我们只需要在application.properties文件中配置以spring.message开头的配置即可</p>
<pre><code>spring.messages.basename=i18n.login
</code></pre>
<p>3）页面获取国际化值</p>
<p>前台模板使用thymeleaf，使用 <code>th:text=&quot;#{login.btn}&quot;</code>取值</p>
<pre><code class="language-html">&lt;h1 class=&quot;h3 mb-3 font-weight-normal&quot; th:text=&quot;#{login.tip}&quot;&gt;Please sign in&lt;/h1&gt;
</code></pre>
<hr>
<p>疑问：如何实现：页面点击“中文”，使用中文的国际化；页面点击“EN”使用英文的国际化？如图：</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708100835.png" alt=""></p>
<p>1）页面标签写法</p>
<pre><code class="language-html">	&lt;a class=&quot;btn btn-sm&quot; th:href=&quot;@{/index.html(l='zh_CN')}&quot;&gt;中文&lt;/a&gt;
	&lt;a class=&quot;btn btn-sm&quot; th:href=&quot;@{/index.html(l='en_US')}&quot;&gt;English&lt;/a&gt;
</code></pre>
<p>2）自定义一个LocaleResolver</p>
<pre><code class="language-java">package com.demo.component;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/**
 * 自定义的国际化解析器
 *
 * 实现了：页面点击“中文”，使用中文的国际化；页面点击“EN”使用英文的国际化
 *
 * Created by lwx on 2019/6/9.
 */
public class MyLocalResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest rq) {
        //http://localhost:8080/index.html?l=zh_CN
        String l = rq.getParameter(&quot;l&quot;);
        Locale locale = Locale.getDefault();
        if (!StringUtils.isEmpty(l)) {
            String[] arr = l.split(&quot;_&quot;);
            locale = new Locale(arr[0],arr[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

    }
}
</code></pre>
<p>他的原理是改变Locale的值。</p>
<p>3）在java配置文件中配置成一个bean</p>
<pre><code class="language-java">    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocalResolver();
    }
</code></pre>
<p>参考代码：https://github.com/wolf-lea/spring-boot-v1520-demo/tree/master/31-spring-boot-atguigu-crud</p>
<h1 id="spring-boot-启动配置原理">Spring Boot 启动配置原理</h1>
<p>教程参考：https://ke.qq.com/course/403245?taid=3394046366459693</p>
<h2 id="启动原理">启动原理</h2>
<p>TODO&hellip;</p>
<h2 id="运行流程">运行流程</h2>
<h2 id="自动配置原理">自动配置原理</h2>
<h2 id="如何修改spring-boot的默认配置">如何修改Spring Boot的默认配置</h2>
<p>1）SpringBoot在自动配置很多组件时，都会用@ConditionalOnxxx来判断有没有用户自己配置的（@Bean,@Component），如果有就用用户配置的，如果没有才自动配置；如果有些组件有多个（如ViewResolver），则将用户配置和默认配置组合起来；</p>
<p>2）在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置</p>
<h1 id="自定义starter">自定义starter</h1>
<p>TODO..</p>

    </div>
    <div class="article-footer">
<blockquote class="mt-2x">
  <ul class="post-copyright list-unstyled">
    <li class="post-copyright-link hidden-xs">
      <strong>Permalink: </strong>
      <a href="https://rulerLwx.gitee.io/2020/07/java-framework-springboot-2/" title="Java-framework-SpringBoot-2" target="_blank" rel="external">https://rulerLwx.gitee.io/2020/07/java-framework-springboot-2/</a>
    </li>
    <li class="post-copyright-license">
      <strong>License：</strong><a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN</a>
    </li>
  </ul>
</blockquote>

<div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="https://gitee.com/rulerLwx" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="https://rulerLwx.gitee.io/avatar.png" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="https://gitee.com/rulerLwx" target="_blank"><span class="text-dark">rulerLwx</span><small class="ml-1x">thinking...</small></a></h3>
        <div>Good Good Study, Day Day Up~</div>
      </div>
    </figure>
  </div>
</div>
    </div>
  </article>
<section id="comments">
    <div id="vcomments"></div>
</section>

</div><nav class="bar bar-footer clearfix" data-stick-bottom>
    <div class="bar-inner">
        <ul class="pager pull-left">
            <li class="prev">
                <a href="https://rulerLwx.gitee.io/2020/07/java-framework-springboot-3-%E4%BA%8B%E5%8A%A1/" title="Java-framework-SpringBoot-3-事务"><i
                        class="icon icon-angle-left"
                        aria-hidden="true"></i><span>&nbsp;&nbsp;Older</span></a>
            </li>
            <li class="next">
                <a href="https://rulerLwx.gitee.io/2020/07/java-framework-springboot-1/"
                    title="Java-framework-SpringBoot-1"><span>Newer&nbsp;&nbsp;</span><i
                        class="icon icon-angle-right" aria-hidden="true"></i></a>
            </li>
            
            <li class="toggle-toc">
                <a class="toggle-btn collapsed" data-toggle="collapse" href="#collapseToc" aria-expanded="false"
                    title="Catalogue" role="button">
                    <span>[&nbsp;</span><span>Catalogue</span>
                    <i class="text-collapsed icon icon-anchor"></i>
                    <i class="text-in icon icon-close"></i>
                    <span>]</span>
                </a>
            </li>
        </ul>
        <div class="bar-right">
            <div class="share-component" data-sites="weibo,qq,wechat"
                data-mobile-sites="weibo,qq,qzone"></div>
        </div>
    </div>
</nav>

</main><footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
<ul class="social-links">
    <li><a href="https://gitee.com/rulerLwx" target="_blank" title="gitee" data-toggle=tooltip data-placement=top >
            <i class="icon icon-gitee"></i></a></li>
    <li><a href="https://github.com/wolf-lea" target="_blank" title="github" data-toggle=tooltip data-placement=top >
            <i class="icon icon-github"></i></a></li>
</ul>
  <div class="copyright">
    &copy;2020  -
    2020
    <div class="publishby">
        Theme by <a href="https://github.com/xiaoheiAh" target="_blank"> xiaoheiAh </a>base on<a href="https://github.com/xiaoheiAh/hugo-theme-pure" target="_blank"> pure</a>.
    </div>
  </div>
</footer>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_SVG"></script>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
            showMathMenu: false, //disables context menu
            tex2jax: {
            inlineMath: [ ['$','$'], ['\\(','\\)'] ]
           }
    });
</script>


<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>
<script>
    window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/highlight.min.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/python.min.js" defer></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/javascript.min.js" defer></script><script>
    hljs.configure({
        tabReplace: '    ', 
        classPrefix: ''     
        
    })
    hljs.initHighlightingOnLoad();
</script>
<script src="https://rulerLwx.gitee.io/js/application.min.bdeb64b910570b6c41badc6a05b7afb0c8ad9efd8525de3c7257d59e786326a3.js"></script>
<script src="https://rulerLwx.gitee.io/js/plugin.min.51ff8c7317566f82259170fa36e09c4493adc9b9378b427a01ad3f017ebac7dd.js"></script>

<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: 'Posts',
                PAGES: 'Pages',
                CATEGORIES: 'Categories',
                TAGS: 'Tags',
                UNTITLED: '(Untitled)',
            },
            ROOT_URL: 'https:\/\/rulerLwx.gitee.io',
            CONTENT_URL: 'https:\/\/rulerLwx.gitee.io\/searchindex.json ',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script type="text/javascript" src="https://rulerLwx.gitee.io/js/insight.min.a343cd9a5a7698336b28ef3a7c16a3a1b1d2d5fb17dc8ed04022bbe08cc5459073a15bdafa3a8a58cdd56080784bdd69fa70b1ae8597565c799c57ed00f0e120.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.min.js"></script>
<script>
    tocbot.init({
        
        tocSelector: '.js-toc',
        
        contentSelector: '.js-toc-content',
        
        headingSelector: 'h1, h2, h3',
        
        hasInnerContainers: true,
    });
</script>

<script src="https://cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine"></script>
<script type="text/javascript">
    var GUEST = ['nick', 'mail', 'link'];
    var meta = 'nick,mail';
    meta = meta.split(',').filter(function (item) {
        return GUEST.indexOf(item) > -1;
    });
    new Valine({
        el: '#vcomments',
        verify: null ,
        notify: null ,
        appId: 'IyAB0PSPRazTPDxitO1ddQ7O-gzGzoHsz',
        appKey: '5rBJTq4KidYF33eXwvRVhtEH',
        placeholder: 'enjoy~',
        avatar: 'mm',
        meta: meta,
        pageSize: '10' || 10,
        visitor: false 
});
</script>

  </body>
</html>
